// 什么是抽象类？  为子类服务的类型   类似接口 在 抽象类中定义的属性 在子类中必须存在

// 首先，抽象类是不允许被实例化的：

abstract class Y {
    abstract name1: string; //抽象属性
    name22: string

    constructor(name22: string) {
        this.name22 = name22;  //报错
    }

    abstract sayhi(): void; //{} 抽象方法不能有具体的实现
}

// const y = new Y()无法创建抽象类的实例


class Dogg extends Y {
    name1: string;

    constructor(name1: string) {
        super(name1);
        this.name1 = name1;
    }

    sayhi() {
        console.log(222);
    }
}

const d = new Dogg("小狗");
console.log(d.name22);
console.log(d.name1)
d.sayhi();


// 如何让抽象类实现

abstract class School {
    abstract name: string
    abstract address: string
    schoolName: string
    constructor(schoolName: string) {
        this.schoolName = schoolName
    }
    abstract getSchoolAddress(): string
    getStudent(): string {
        return "小王"
    }
}

class Student extends School {
    address: string;
    name: string;

    constructor(name: string, address: string, schoolName: string) {
        super(schoolName);
        this.name = name;
        this.address = address;
    }

    getSchoolAddress(): string {
        return "江苏南京";
    }

}

// 可以借用构造签名
function getStu(ctor: { new(name: string, address: string, schoolName: string): School }, schoolName: string) {
    const instance = new ctor("ada", "as", schoolName)
    instance.getStudent()
}

getStu(Student, "清华大学")





// 类的类型  给类加上 TypeScript 的类型很简单，与接口类似：  类的兼容性
class DCar {
    name: string;

    constructor(name: string) {
        this.name = name;
    }
}

class Ben {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}

// 类型 "DCar" 中缺少属性 "age"，但类型 "Ben" 中需要该属性。
// const dcar:  Ben = new DCar('')
const ben: DCar = new Ben("10", 1);



